home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Reverse Code Engineering RCE CD +sandman 2000
/
ReverseCodeEngineeringRceCdsandman2000.iso
/
RCE
/
Bill's Win32Asm Page
/
vga1.txt
< prev
Wrap
Text File
|
2000-05-25
|
6KB
|
168 lines
VGA Programming in Mode 13h
-----------------------------------------------------------------------------
This article will describe how to program VGA graphics Mode 13h using
assembly language. Mode 13h is the 320x200x256 graphics mode, and is fast
and very convenient from a programmers perspective.
The video buffer begins at address A000:0000 and ends at address A000:F9FF.
This means the buffer is 64000 bytes long and that each pixel in mode 13h
is represented by one byte.
It is easy to set up mode 13h and the video buffer in assembly language:
mov ax,0013h ; Int 10 - Video BIOS Services
int 10h ; ah = 00 - Set Video Mode
; al = 13 - Mode 13h (320x200x256)
mov ax,0A000h ; point segment register es to A000h
mov es,ax ; we can now access the video buffer as
; offsets from register es
At the end of your program, you will probably want to restore the text
mode. Here's how:
mov ax,0003h ; Int 10 - Video BIOS Services
int 10h ; ah = 00 - Set Video Mode
; al = 03 - Mode 03h (80x25x16 text)
Accessing a specific pixel int the buffewr is also very easy:
; bx = x coordinate
; ax = y coordinate
imul ax, 320 ; multiply y coord by 320 to get row
add bx,ax ; add this with the x coord to get offset
mov cx,es:[bx] ; now pixel x,y can be accessed as es:[bx]
Hmm... That was easy, but that multiplication is slow and we should get
rid of it. Thats easy to do too, simply by using bit shifting instead of
multiplication. Shifting a number to the left is the same as multiplying
by 2. We want to multiply by 320, which is not a multiple of 2, but
320 = 256 + 64, and 256 and 64 are both even multiples of 2. So a faster
way to access a pixel is:
; bx = x coordinate
; ax = y coordinate
mov cx,bx ; copy bx to cx, to save it temporatily
shl cx,8 ; shift left by 8, which is the same as
; multiplying by 2^8 = 256
shl bx,6 ; now shift left by 6, which is the same as
; multiplying by 2^6 = 64
add bx,cx ; now add those two together, whis is
; effectively multiplying by 320
add bx,ax ; finally add the x coord to this value
mov cx,es:[bx] ; now pixel x,y can be accessed as es:[bx]
Well, the code is a little bit longer and looks more complicated, but I
can guarantee its much faster.
To plot colors, we use a color look-up table. This look-up table is a
768 (3x256) array. Each index of the table is really the offset index*3.
The 3 bytes at each index hold the corresponding values (0-63) of the red,
green, and blue components. This gives a total of 262144 total possible
colors. However, since the table is only 256 elements big, only 256
different colors are possible at a given time.
Changing the color palette is accomplished through the use of the I/O
ports of the VGA card:
Port 03C7h is the Palette Register Read port.
Port 03C8h is the Palette Register Write port
Port 03C9h is the Palette Data port
Here is how to change the color palette:
; ax = palette index
; bl = red component (0-63)
; cl = green component (0-63)
; dl = blue component (0-63)
mov dx,03C8h ; 03c8h = Palette Register Write port
out dx,ax ; choose index
mov dx,03C9h ; 03c8h = Palette Data port
out dx,al
mov bl,al ; set red value
out dx,al
mov cl,al ; set green value
out dx,al
mov dl,al ; set blue value
Thats all there is to it. Reading the color palette is similar:
; ax = palette index
; bl = red component (0-63)
; cl = green component (0-63)
; dl = blue component (0-63)
mov dx,03C7h ; 03c7h = Palette Register Read port
out dx,ax ; choose index
mov dx,03C9h ; 03c8h = Palette Data port
in al,dx
mov bl,al ; get red value
in al,dx
mov cl,al ; get green value
in al,dx
mov dl,al ; get blue value
Now all we need to know is how to plot a pixel of a certain color at a
certain location. Its very easy, given what we already know:
; bx = x coordinate
; ax = y coordinate
; dx = color (0-255)
mov cx,bx ; copy bx to cx, to save it temporatily
shl cx,8 ; shift left by 8, which is the same as
; multiplying by 2^8 = 256
shl bx,6 ; now shift left by 6, which is the same as
; multiplying by 2^6 = 64
add bx,cx ; now add those two together, whis is
; effectively multiplying by 320
add bx,ax ; finally add the x coord to this value
mov es:[bx],dx ; copy color dx into memory location
; thats all there is to it
Ok, we now know how to set up Mode 13h, set up the video buffer, plot a
pixel, and edit the color palette.
My next article will go on to show how to draw lines, utilize the vertical
retrace for smoother rendering, and anything else i can figure out by
that time...
-----------------------------------------------------------------------------
Copyright (C) 1998
Bill T. (billasm@usa.net)